/*!
 * @file       apm32f10x_dma.h
 *
 * @brief      This file contains all the functions prototypes for the DMA firmware library
 *
 * @version    V1.0.0
 *
 * @date       2019-8-6
 *
 */

#ifndef __APM32F10x_DMA_H
#define __APM32F10x_DMA_H

#ifdef __cplusplus
extern "C" {
#endif

#include "apm32f10x.h"

/**
 * @brief   DMA Transmission direction
 */
typedef enum
{
  DMA_DOT_PERIPHERAL_SRC,
  DMA_DOT_PERIPHERAL_DST
} DMA_DOT;

/**
 * @brief   DMA Peripheral address Loop
 */
typedef enum
{
  DMA_PERIPHERAL_LOOP_DISABLE,
  DMA_PERIPHERAL_LOOP_ENABLE
} DMA_PERIPHERAL_LOOP;

/**
 * @brief   DMA Memory address Loop
 */
typedef enum
{
  DMA_MEMORY_LOOP_DISABLE,
  DMA_MEMORY_LOOP_ENABLE
} DMA_MEMORY_LOOP;

/**
 * @brief   DMA Peripheral Data Size
 */
typedef enum
{
  DMA_PERIPHERAL_DATA_SIZE_BYTE,
  DMA_PERIPHERAL_DATA_SIZE_HALFWORD,
  DMA_PERIPHERAL_DATA_SIZE_WOED
} DMA_PERIPHERAL_DATA_SIZE;

/**
 * @brief   DMA Memory Data Size
 */
typedef enum
{
  DMA_MEMORY_DATA_SIZE_BYTE,
  DMA_MEMORY_DATA_SIZE_HALFWORD,
  DMA_MEMORY_DATA_SIZE_WOED
} DMA_MEMORY_DATA_SIZE;

/**
 * @brief   DMA Mode
 */
typedef enum
{
  DMA_MODE_NORMAL,
  DMA_MODE_CIRCULAR
} DMA_LOOP_MODE;

/**
 * @brief   DMA priority level
 */
typedef enum
{
  DMA_PRIORITY_LOW,
  DMA_PRIORITY_MEDIUM,
  DMA_PRIORITY_HIGH,
  DMA_PRIORITY_VERYHIGH
} DMA_PRIORITY;

/**
 * @brief   DMA Memory to Memory
 */
typedef enum
{
  DMA_M2MEN_DISABLE,
  DMA_M2MEN_ENABLE
} DMA_M2MEN;

/**
 * @brief    DMA Config struct definition
 */
typedef struct
{
  uint32_t PeripheralBaseAddr;
  uint32_t MemoryBaseAddr;
  DMA_DOT  DOT;
  uint32_t BufferSize;
  DMA_PERIPHERAL_LOOP PLoop;
  DMA_MEMORY_LOOP MLoop;
  DMA_PERIPHERAL_DATA_SIZE PeripheralDataSize;
  DMA_MEMORY_DATA_SIZE MemoryDataSize;
  DMA_LOOP_MODE DMA_LoopMode;
  DMA_PRIORITY DMA_Priority;
  DMA_M2MEN M2M;
} DMA_Config_T;


/**
 * @brief   DMA interrupt
 */
typedef enum
{
  DMA_IT_EOT = 0x00000002,
  DMA_IT_MOT = 0x00000004,
  DMA_IT_FOT = 0x00000008
} DMA_IT;

/**
 * @brief   DMA Flag
 */
typedef enum
{
  DMA1_FLAG_GIFC1     = 0x00000001,
  DMA1_FLAG_EOTIFC1   = 0x00000002,
  DMA1_FLAG_MOTIFC1   = 0x00000004,
  DMA1_FLAG_FOTIFC1   = 0x00000008,
  DMA1_FLAG_GIFC2     = 0x00000010,
  DMA1_FLAG_EOTIFC2   = 0x00000020,
  DMA1_FLAG_MOTIFC2   = 0x00000040,
  DMA1_FLAG_FOTIFC2   = 0x00000080,
  DMA1_FLAG_GIFC3     = 0x00000100,
  DMA1_FLAG_EOTIFC3   = 0x00000200,
  DMA1_FLAG_MOTIFC3   = 0x00000400,
  DMA1_FLAG_FOTIFC3   = 0x00000800,
  DMA1_FLAG_GIFC4     = 0x00001000,
  DMA1_FLAG_EOTIFC4   = 0x00002000,
  DMA1_FLAG_MOTIFC4   = 0x00004000,
  DMA1_FLAG_FOTIFC4   = 0x00008000,
  DMA1_FLAG_GIFC5     = 0x00010000,
  DMA1_FLAG_EOTIFC5   = 0x00020000,
  DMA1_FLAG_MOTIFC5   = 0x00040000,
  DMA1_FLAG_FOTIFC5   = 0x00080000,
  DMA1_FLAG_GIFC6     = 0x00100000,
  DMA1_FLAG_EOTIFC6   = 0x00200000,
  DMA1_FLAG_MOTIFC6   = 0x00400000,
  DMA1_FLAG_FOTIFC6   = 0x00800000,
  DMA1_FLAG_GIFC7     = 0x01000000,
  DMA1_FLAG_EOTIFC7   = 0x02000000,
  DMA1_FLAG_MOTIFC7   = 0x04000000,
  DMA1_FLAG_FOTIFC7   = 0x08000000,

  DMA2_FLAG_GIFC1     = 0x10000001,
  DMA2_FLAG_EOTIFC1   = 0x10000002,
  DMA2_FLAG_MOTIFC1   = 0x10000004,
  DMA2_FLAG_FOTIFC1   = 0x10000008,
  DMA2_FLAG_GIFC2     = 0x10000010,
  DMA2_FLAG_EOTIFC2   = 0x10000020,
  DMA2_FLAG_MOTIFC2   = 0x10000040,
  DMA2_FLAG_FOTIFC2   = 0x10000080,
  DMA2_FLAG_GIFC3     = 0x10000100,
  DMA2_FLAG_EOTIFC3   = 0x10000200,
  DMA2_FLAG_MOTIFC3   = 0x10000400,
  DMA2_FLAG_FOTIFC3   = 0x10000800,
  DMA2_FLAG_GIFC4     = 0x10001000,
  DMA2_FLAG_EOTIFC4   = 0x10002000,
  DMA2_FLAG_MOTIFC4   = 0x10004000,
  DMA2_FLAG_FOTIFC4   = 0x10008000,
  DMA2_FLAG_GIFC5     = 0x10010000,
  DMA2_FLAG_EOTIFC5   = 0x10020000,
  DMA2_FLAG_MOTIFC5   = 0x10040000,
  DMA2_FLAG_FOTIFC5   = 0x10080000
} DMA_FLAG;

/**
 * @brief   DMA Flag
 */
typedef enum
{
  DMA1_INT_GIFC1     = 0x00000001,
  DMA1_INT_EOTIFC1   = 0x00000002,
  DMA1_INT_MOTIFC1   = 0x00000004,
  DMA1_INT_FOTIFC1   = 0x00000008,
  DMA1_INT_GIFC2     = 0x00000010,
  DMA1_INT_EOTIFC2   = 0x00000020,
  DMA1_INT_MOTIFC2   = 0x00000040,
  DMA1_INT_FOTIFC2   = 0x00000080,
  DMA1_INT_GIFC3     = 0x00000100,
  DMA1_INT_EOTIFC3   = 0x00000200,
  DMA1_INT_MOTIFC3   = 0x00000400,
  DMA1_INT_FOTIFC3   = 0x00000800,
  DMA1_INT_GIFC4     = 0x00001000,
  DMA1_INT_EOTIFC4   = 0x00002000,
  DMA1_INT_MOTIFC4   = 0x00004000,
  DMA1_INT_FOTIFC4   = 0x00008000,
  DMA1_INT_GIFC5     = 0x00010000,
  DMA1_INT_EOTIFC5   = 0x00020000,
  DMA1_INT_MOTIFC5   = 0x00040000,
  DMA1_INT_FOTIFC5   = 0x00080000,
  DMA1_INT_GIFC6     = 0x00100000,
  DMA1_INT_EOTIFC6   = 0x00200000,
  DMA1_INT_MOTIFC6   = 0x00400000,
  DMA1_INT_FOTIFC6   = 0x00800000,
  DMA1_INT_GIFC7     = 0x01000000,
  DMA1_INT_EOTIFC7   = 0x02000000,
  DMA1_INT_MOTIFC7   = 0x04000000,
  DMA1_INT_FOTIFC7   = 0x08000000,

  DMA2_INT_GIFC1     = 0x10000001,
  DMA2_INT_EOTIFC1   = 0x10000002,
  DMA2_INT_MOTIFC1   = 0x10000004,
  DMA2_INT_FOTIFC1   = 0x10000008,
  DMA2_INT_GIFC2     = 0x10000010,
  DMA2_INT_EOTIFC2   = 0x10000020,
  DMA2_INT_MOTIFC2   = 0x10000040,
  DMA2_INT_FOTIFC2   = 0x10000080,
  DMA2_INT_GIFC3     = 0x10000100,
  DMA2_INT_EOTIFC3   = 0x10000200,
  DMA2_INT_MOTIFC3   = 0x10000400,
  DMA2_INT_FOTIFC3   = 0x10000800,
  DMA2_INT_GIFC4     = 0x10001000,
  DMA2_INT_EOTIFC4   = 0x10002000,
  DMA2_INT_MOTIFC4   = 0x10004000,
  DMA2_INT_FOTIFC4   = 0x10008000,
  DMA2_INT_GIFC5     = 0x10010000,
  DMA2_INT_EOTIFC5   = 0x10020000,
  DMA2_INT_MOTIFC5   = 0x10040000,
  DMA2_INT_FOTIFC5   = 0x10080000
} DMA_INT;

/*  Function used to set the DMA configuration to the default reset state *****/
void DMA_Reset(DMA_Channel_T *DMAx_Channely);

/* Initialization and Configuration functions *********************************/
void DMA_Config(DMA_Channel_T* DMAx_Channely, DMA_Config_T* DMA_ConfigStruct);
void DMA_StructInit( DMA_Config_T* DMA_ConfigStruct);
void DMA_ENABLE(DMA_Channel_T *DMAx_Channely);
void DMA_DISABLE(DMA_Channel_T *DMAx_Channely);
void DMA_SetCurrDataCounter(DMA_Channel_T *DMAx_Channely, uint16_t dataNumber);
uint16_t DMA_ReadCurrDataCounter(DMA_Channel_T *DMAx_Channely);

/* Interrupts and flags management functions **********************************/
void DMA_IntEnable(DMA_Channel_T *DMAx_Channely, DMA_IT DMA_interrupus);
void DMA_IntDisable(DMA_Channel_T *DMAx_Channely, DMA_IT DMA_interrupus);
uint8_t DMA_ReadFlagState(DMA_FLAG flag);
void DMA_ClearFlag(DMA_FLAG flag);
uint8_t DMA_ReadIntState(DMA_INT interrupt);
void DMA_ClearIntFlag(DMA_INT interrupt);

#ifdef __cplusplus
}
#endif

#endif /* __APM32F10x_DMA_H */
